package br.edu.ufcg.lsd.wbis.control.equipment;

import java.sql.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import org.hibernate.annotations.CollectionOfElements;

import br.edu.ufcg.lsd.wbis.control.user.User;

/**
 * 
 * @author Paulo Ricardo
 *
 */
@Entity
public class Computer extends Equipment {

	@Enumerated(EnumType.STRING)
	private ComputerType computerType;
	
	@OneToOne()
	@JoinColumn(name="ownerLogin", nullable=true)
	private User owner;

	@CollectionOfElements
	private Set<String> services;
	
	private int numProcessors;
	
	private int numHDs;

	@OneToMany()
	@JoinColumn(name="computerId")
	private Set<Component> components;
	
	/**
	 * 
	 * @param inventoryCode
	 * @param brand
	 * @param serialCode
	 * @param aquisitionDate
	 * @param model
	 * @param localization
	 * @param receipt
	 * @param alocable
	 * @param available
	 * @param server
	 * @param owner
	 * @param services
	 * @param numProcessors
	 * @param numHDs
	 */
	public Computer(String inventoryCode, String brand, String serialCode,
			Date aquisitionDate, String model, String localization,
			byte[] receipt, boolean alocable, boolean available, ComputerType computerType, User owner, int numProcessors, int numHDs) {
		super(inventoryCode, brand, serialCode, aquisitionDate, model, localization,
				receipt, alocable, available, Computer.class);
		this.computerType = computerType;
		this.services = new HashSet<String>();
		this.components = new HashSet<Component>();
		this.numProcessors = 1;
		this.numHDs = 1;
		this.owner = null;
		if(this.computerType.equals(ComputerType.SERVER)){
			this.numProcessors = numProcessors;
			this.numHDs = numHDs;
		} else if(computerType.equals(ComputerType.CLIENT)){
			this.owner = owner;
		}
		
	}
	
	@SuppressWarnings("unused")
	private Computer(){};

	/**
	 * 
	 * @param server
	 */
	protected void setComputerType(ComputerType computerType) {
		this.computerType = computerType;
	}

	/**
	 * 
	 * @param owner
	 */
	protected void setOwner(User owner) {
		this.owner = owner;
	}

	/**
	 * 
	 * @param services
	 */
	@SuppressWarnings("unused")
	private void setServices(Set<String> services) {
		this.services = services;
	}

	/**
	 * 
	 * @param numProcessors
	 */
	protected void setNumProcessors(int numProcessors) {
		this.numProcessors = numProcessors;
	}

	/**
	 * 
	 * @param numHDs
	 */
	protected void setNumHDs(int numHDs) {
		this.numHDs = numHDs;
	}

	/**
	 * 
	 * @return
	 */
	public ComputerType getComputerType() {
		return computerType;
	}

	/**
	 * 
	 * @return
	 */
	public User getOwner() {
		return owner;
	}

	/**
	 * 
	 * @return
	 */
	public Set<String> getServices() {
		return services;
	}

	/**
	 * 
	 * @return
	 */
	public int getNumProcessors() {
		return numProcessors;
	}

	/**
	 * 
	 * @return
	 */
	public int getNumHDs() {
		return numHDs;
	}

	/**
	 * 
	 * @return
	 */
	public Set<Component> getComponents() {
		return components;
	}

	/**
	 * 
	 * @param component
	 * @return
	 */
	public boolean addComponent(Component component){
		return components.add(component);
	}
	
	/**
	 * 
	 * @param service
	 * @return
	 */
	public boolean addService(String service){
		return services.add(service);
	}
	
	/**
	 * 
	 * @param service
	 * @return
	 */
	public boolean removeService(String service){
		return services.remove(service);
	}
	
	/**
	 * 
	 * @param components
	 */
	protected void setComponents(Set<Component> components) {
		this.components = components;
	}

	/**
	 * 
	 * @param component
	 */
	public boolean removeComponent(Component component) {
		return components.remove(component);
	}
	
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result
				+ ((components == null) ? 0 : components.hashCode());
		result = prime * result
				+ ((computerType == null) ? 0 : computerType.hashCode());
		result = prime * result + numHDs;
		result = prime * result + numProcessors;
		result = prime * result + ((owner == null) ? 0 : owner.hashCode());
		result = prime * result
				+ ((services == null) ? 0 : services.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		Computer other = (Computer) obj;
		if (components == null) {
			if (other.components != null)
				return false;
		} else if (!components.equals(other.components))
			return false;
		if (computerType == null) {
			if (other.computerType != null)
				return false;
		} else if (!computerType.equals(other.computerType))
			return false;
		if (numHDs != other.numHDs)
			return false;
		if (numProcessors != other.numProcessors)
			return false;
		if (owner == null) {
			if (other.owner != null)
				return false;
		} else if (!owner.equals(other.owner))
			return false;
		if (services == null) {
			if (other.services != null)
				return false;
		} else if (!services.equals(other.services))
			return false;
		return true;
	}
	
}
